package com.demo2do.wechatmcs.handle.impl;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.http.annotation.Rao;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.wechat.rao.wechat.WechatTokenRao;
import com.demo2do.core.wechat.utils.WechatUtils;
import com.demo2do.wechatmcs.CacheKeys;
import com.demo2do.wechatmcs.entity.token.JsTicket;
import com.demo2do.wechatmcs.entity.token.Token;
import com.demo2do.wechatmcs.handle.WechatTokenHandler;

/**
 * 
 * @author mohanlan
 *
 */
@Component("wechatTokenHandler")
public class WechatTokenHandlerImpl implements WechatTokenHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(WechatTokenHandlerImpl.class);
    
    private static final String JS_TICKET_TYPE = "jsapi";
    
    @Rao
    private WechatTokenRao wechatTokenRao;
    
    @Value("#{wechat['wechat.appid']}")
    private String appid;
    
    @Value("#{wechat['wechat.appsecret']}")
    private String appsecret;
    
    
    /* (non-Javadoc)
     * @see com.demo2do.wechatmcs.handle.WechatTokenHandler#requestAccessToken()
     */
    @Cacheable(CacheKeys.Wechat.ACCESS_TOKEN)
    public Token requestAccessToken() {

        logger.info("#requestAccessToken - Request global access_token for appid[{}] and appsecret[{}]", this.appid, this.appsecret);
        
        // 1. call rao to get access token
        HttpResult httpResult = wechatTokenRao.getAccessToken(appid, appsecret);
        
        if(WechatUtils.isValid(httpResult)) {  // this is a valid response
            
            // 2. get response data
            Map<String, Object> response = httpResult.describe();
            
            String accessToken = (String) response.get("access_token");
            Integer expireTime = (Integer) response.get("expires_in");
            
            return new Token(accessToken, expireTime);
        
        }
        
        throw WechatUtils.toBusinessException(httpResult);
        
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.wechatmcs.handle.WechatTokenHandler#requestJsTicket()
     */
    @Cacheable(CacheKeys.Wechat.JS_TICKET)
    public JsTicket requestJsTicket() {
        
        // 1. get global access_token
        String accessToken = this.requestAccessToken().getAccessToken();  // an internal call will always return correct access_token

        
        logger.info("#requestJsTicket - Start get js ticket with accessToken[{}]", accessToken);
        
        // 2. call rao to get js_ticket
        HttpResult httpResult = wechatTokenRao.getJsTicket(accessToken, JS_TICKET_TYPE);

        if(WechatUtils.isValid(httpResult)) {  // this is a valid response, let's return ticket
            
            // get ticket from response
            String ticket = (String) httpResult.describe().get("ticket");
            
            return new JsTicket(this.appid, ticket);
        
        }
        
        logger.info("#requestJsTicket - get js ticket result[{}], responseText[{}]", JsonUtils.toJson(httpResult), httpResult.getResponseText());
        
        throw WechatUtils.toBusinessException(httpResult); 
        
    }

}
